﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;

public class MapEditor : EditorWindow
{

    Scene _scene;



    int newwidth = 16;
    int newheight = 16;

    // Use this for initialization
    void OnGUI()
    {
        if(_scene == null)
        {
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("新建地图"))
            {
                NewMap();
            }
            newwidth = EditorGUILayout.IntField(newwidth);
            newheight = EditorGUILayout.IntField(newheight);
            EditorGUILayout.EndHorizontal();
            if (GUILayout.Button("打开地图"))
            {
                OpenMap();
            }
        }
        else
        {
            if (GUILayout.Button("保存地图"))
            {
                SaveMap();
            }
            if (GUILayout.Button("关闭地图"))
            {
                if (EditorUtility.DisplayDialog("确定要关闭地图嘛", "关闭地图为保存的数据将丢失", "关闭", "等等"))
                {
                    EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
                }
            }
            if (_currentSelected != null)
            {
                GuiMatterGrid(_currentSelected);
                _currentSelected.BroadCastUpdateEvent();
            }
            else if (_currentSelectedMutli != null)
            {
                GuiMatterGrid(_currentSelectedMutli);
                for(int i = 0 ; i < _currentSelectedMutli.Length;i++)
                {
                    _currentSelectedMutli[i].BroadCastUpdateEvent();
                }
            }
            else
            {
                GUILayout.Label("请在scene面板上选中一个物体");
            }
        }

    }


    void Update()
    {
        if (_scene == null)
        {
            return;
        }

        if (UnityEditor.Selection.activeGameObject)
        {
            MatterGridBehaviour mgb = UnityEditor.Selection.activeGameObject.GetComponentInParent<MatterGridBehaviour>();
            if (mgb != null)
            {
                SetSelectMatterGrid(mgb.mg);
            }
        }
        if(UnityEditor.Selection.gameObjects.Length > 0)
        {
            List<MatterGrid> mgbs = new List<MatterGrid>();
            for(int i = 0 ; i < UnityEditor.Selection.gameObjects.Length;i++)
            {
                MatterGridBehaviour mgb = Selection.gameObjects[i].GetComponent<MatterGridBehaviour>();
                if(mgb != null && !mgbs.Contains(mgb.mg))
                {
                    mgbs.Add(mgb.mg);
                }
            }
            if(mgbs.Count >1 )
            {
                SetSelectMatterGridMutli(mgbs.ToArray());
            }
        }


    }

    int GetMatterIndex(Matter m)
    {
        for (int i = 0; i < MatterTypeConfig.MatterNames.Length; i++)
        {
            if (m.matterType.Name == MatterTypeConfig.MatterNames[i])
            {
                return i;
            }
        }
        return -1;
    }

    int GetStateIndex(string str)
    {
        for (int i = 0; i < MatterStates.Length; i++)
        {
            if (str == MatterStates[i])
            {
                return i;
            }
        }
        return -1;
    }

    string[] MatterStates = { "固体", "液体", "气体" };
    int _toAddMatterIndex = 0;


    void GuiProperty(string name,ref bool value)
    {
        value = EditorGUILayout.Toggle(name, value);
    }

    float GuiProperty(string name,ref float value)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField(name);
        value = EditorGUILayout.FloatField(value);        
        EditorGUILayout.EndHorizontal();
        return value;
    }

    float GuiProperty(string name, float value)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField(name);
        value = EditorGUILayout.FloatField(value);
        EditorGUILayout.EndHorizontal();
        return value;
    }

    MatterGrid _copyMg;

    void GuiMatterGrid(MatterGrid mg)
    {
        GUIStyle gs = new GUIStyle(GUI.skin.label);
        gs.normal.textColor = Color.red;
        float temperature = GuiProperty("温度", mg.Temperature);
        if(temperature != mg.Temperature)
        {
            mg.SetAllMatterTemperature(temperature);
        }

        GuiProperty("锁定温度",ref mg.LockTemperature);
        GuiProperty("不能挖", ref mg.CannotDig);
        GuiProperty("锁定气体", ref mg.LockAir);


        for (int i = 0; i < mg.Matters.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("物质名称");
            int matterIndex = GetMatterIndex(mg.Matters[i]);
            int afterEditorMatterIndex = EditorGUILayout.Popup(matterIndex, MatterTypeConfig.MatterNames);
            if (afterEditorMatterIndex != matterIndex)
            {
                mg.Matters[i].matterType = MatterTypeConfig.AllMatters[MatterTypeConfig.MatterNames[afterEditorMatterIndex]];
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("物质质量");
            mg.Matters[i].Mass = EditorGUILayout.FloatField(mg.Matters[i].Mass);
            if (mg.GetTotalVolume() < 1.0f && mg.Matters[i].currentMatterState != Matter.MatterState.Gas)
            {
                if (GUILayout.Button("补足质量"))
                {
                    FillTheGrid(mg, i);
                }

            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("物质状态");
            int stateindex = EditorGUILayout.Popup(GetStateIndex(Matter.ConvertStateToString(mg.Matters[i].currentMatterState)), MatterStates);
            mg.Matters[i].currentMatterState = Matter.ConvertStateFromString(MatterStates[stateindex]);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.LabelField("分割线 ---------------------------------------------", gs);
        }
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("添加一个物体"))
        {
            string name = MatterTypeConfig.MatterNames[_toAddMatterIndex];
            Matter m = new Matter();
            m.matterType = MatterTypeConfig.AllMatters[name];
            m.Mass = 1;
            m.Temperature = mg.Temperature;
            m.CheckMatterState();
            mg.AddMatter(m);
        }

        _toAddMatterIndex = EditorGUILayout.Popup(_toAddMatterIndex, MatterTypeConfig.MatterNames);
        EditorGUILayout.EndHorizontal();
        if (GUILayout.Button("补足空气"))
        {
            FillKongQi(mg);
        }
        if (!CheckVolume(mg))
        {
            EditorGUILayout.LabelField("物体的体积太大 超过了1 ", gs);
        }


        if(GUILayout.Button("拷贝物质"))
        {
            _copyMg = mg;   
        }
//        mg.LockTemperature = EditorGUILayout.Toggle("是否锁定温度", mg.LockTemperature);
    }

    float _temperatureMulti = 20.0f;
    bool _lockTemperature = false;
    bool _cannotdig = false;
    bool _lockair = false;
    void GuiMatterGrid(MatterGrid[] mgs)
    {
        EditorGUILayout.BeginHorizontal();
        if(GUILayout.Button("统一设置温度"))
        {
            foreach(var item in _currentSelectedMutli)
            {
                item.SetAllMatterTemperature(_temperatureMulti);
            }
        }
        _temperatureMulti = EditorGUILayout.FloatField(_temperatureMulti);
        EditorGUILayout.EndHorizontal();

        if(GUILayout.Button("统一补充空气"))
        {
            foreach (var item in _currentSelectedMutli)
            {
                FillKongQi(item);
            }
        }

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("锁定温度"))
        {
            foreach(var item in _currentSelectedMutli)
            {
                item.LockTemperature = _lockTemperature;
            }
        }
        _lockTemperature = GUILayout.Toggle(_lockTemperature, "锁定温度");
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("不能挖"))
        {
            foreach (var item in _currentSelectedMutli)
            {
                item.CannotDig = _cannotdig;
            }
        }
        _cannotdig = GUILayout.Toggle(_cannotdig, "不能挖");
        EditorGUILayout.EndHorizontal();


        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("锁定气体内容"))
        {
            foreach (var item in _currentSelectedMutli)
            {
                item.LockAir = _lockair;
            }
        }
        _lockair = GUILayout.Toggle(_lockair, "锁定气体内容");

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if(GUILayout.Button("粘贴物质"))
        {
            if(_copyMg != null)
            {
                foreach(var item in _currentSelectedMutli)
                {
                    item.ClearMatter();
                    for(int j  =0; j < _copyMg.Matters.Count;j++)
                    {
                        Matter newm = _copyMg.Matters[j].Clone();
                        item.AddMatter(newm);
                    }
                }
            }
        }

        if(GUILayout.Button("清空物质"))
        {
            foreach (var item in _currentSelectedMutli)
            {
                item.ClearMatter();
            }
        }

        EditorGUILayout.EndHorizontal();

    }

    //检查体积检查 体积 是否 超标 因为 质量 和 密度是 确定的 那么体积也是确定的 但是一个格子的体积是1  因此超过1 就是错误的 小于0的将被气体填充 或者真空
    bool CheckVolume(MatterGrid mg)
    {
        return mg.GetTotalVolume() <= 1.0f;
    }

    MatterGrid _currentSelected;
    MatterGrid[] _currentSelectedMutli;
    
    void NewMap()
    {
        EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
        _scene = new Scene();
        _scene.Init(newwidth, newheight);

        for (int i = 0; i < _scene.SceneWidth; i++)
        {
            for (int j = 0; j < _scene.SceneHeight; j++)
            {
                GameObject tile = AssetLoader.Load<GameObject>("Grid" , ".prefab");
                GameObject go = GameObject.Instantiate(tile) as GameObject;
                go.name = i.ToString() + "_" + j.ToString();
                go.transform.localPosition = new Vector2(i, j);
                var grid = go.GetComponent<MatterGridBehaviour>();
                grid.SetMatterGrid(_scene.GetGrid(i, j));
            }
        }
    }

    void OpenMap()
    {
        string mapname = EditorUtility.OpenFilePanel("打开地图", "", "");
        if (!string.IsNullOrEmpty(mapname))
        {
            EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
            System.IO.FileStream fs = System.IO.File.Open(mapname, System.IO.FileMode.Open);
            _scene = Scene.InitFrom(fs);
            fs.Close();

            for (int i = 0; i < _scene.SceneWidth; i++)
            {
                for (int j = 0; j < _scene.SceneHeight; j++)
                {
                    GameObject tile = AssetLoader.Load<GameObject>("Grid" , ".prefab");
                    GameObject go = GameObject.Instantiate(tile) as GameObject;
                    go.name = i.ToString() + "_" + j.ToString();
                    go.transform.localPosition = new Vector2(i, j);
                    var grid = go.GetComponent<MatterGridBehaviour>();
                    grid.SetMatterGrid(_scene.GetGrid(i, j));
                }
            }


        }
    }

    void SaveMap()
    {
        if (_scene == null)
        {
            return;
        }

        string mapname = EditorUtility.SaveFilePanelInProject("保存地图", "", "xml", "");
        if (!string.IsNullOrEmpty(mapname))
        {
            System.IO.Stream str = System.IO.File.Open(mapname, System.IO.FileMode.Create);
            _scene.SaveToStream(str);
            str.Close();
            AssetDatabase.Refresh();
        }
        string mapname2 = mapname.Replace("Assets/", "Assets/Resources/");
        mapname2 = mapname2 + ".txt";
        System.IO.Stream str2 = System.IO.File.Open(mapname2, System.IO.FileMode.Create);
        _scene.SaveToStream(str2);
        str2.Close();
        AssetDatabase.Refresh();        
    }

    void SetSelectMatterGrid(MatterGrid mg)
    {
        _currentSelected = mg;
        _currentSelectedMutli = null;
        Repaint();
    }

    void SetSelectMatterGridMutli(MatterGrid[] mgs)
    {
        _currentSelected = null;
        _currentSelectedMutli = mgs;
        Repaint();
    }

    void OnSceneGUI()
    {
        Debug.Log("OnSceneGUI");
    }

    void OnSceneGUI(SceneView sceneView)
    {
        if (_scene != null)
        {
            int width = _scene.SceneWidth;
            int height = _scene.SceneHeight;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    MatterGrid m = _scene.GetGrid(i, j);
                    //                  Handles.RectangleHandleCap(0, Vector3.zero, Quaternion.identity, 1.0f,Event.current.type);
                    //                  Handles.CubeHandleCap(0, new Vector3(i, j, 0.0f), Quaternion.identity, 0.8f, Event.current.type);
                    //                    if(Handles.Button(new Vector3(i, j, 0.0f), Quaternion.identity, 0.8f, 0.8f, Handles.CubeHandleCap))
                    //                    {
                    //                        SetSelectMatterGrid(i, j);
                    //                    }
                    if (m == _currentSelected)
                    {
                        Handles.RectangleHandleCap(0, new Vector3(i, j, 0.0f), Quaternion.identity, 0.5f, Event.current.type);
                    }
                }
            }
        }
    }

    [MenuItem("Tools/Open MapEditor %g")]
    static void Open()
    {
        EditorWindow.GetWindow<MapEditor>().Show();
    }

    private void Awake()
    {
        SceneView.onSceneGUIDelegate += OnSceneGUI;
    }

    private void OnDestroy()
    {
        SceneView.onSceneGUIDelegate -= OnSceneGUI;
    }


    /// <summary>
    /// 如果 这个格子的质量没有填满 则用改材料填满这个格子
    /// </summary>
    /// <param name="mg"></param>
    /// <param name="index"></param>
    void FillTheGrid(MatterGrid mg, int index)
    {
        float leftVolume = 1.0f - mg.GetTotalVolume();
        if (leftVolume > 0.0f)
        {
            if (mg.Matters[index].currentMatterState == Matter.MatterState.Liquid)
            {
                mg.Matters[index].Mass += leftVolume * mg.Matters[index].matterType.DensityWhenLiquid;
            }
            if (mg.Matters[index].currentMatterState == Matter.MatterState.Solid)
            {
                mg.Matters[index].Mass += leftVolume * mg.Matters[index].matterType.DensityWhenSolid;
            }


        }

    }

    /// <summary>
    /// 按照 正常大气压  78%氮气 21%氧气 1%二氧化碳 补足气体
    /// </summary>
    /// <param name="mg"></param>
    void FillKongQi(MatterGrid mg)
    {
        float totalgas = mg.GetGasVolume();
        AddGas(mg, MatterTypeConfig.AllMatters["氮气"], totalgas * 0.78f);
        AddGas(mg, MatterTypeConfig.AllMatters["氧气"], totalgas * 0.21f);
        AddGas(mg, MatterTypeConfig.AllMatters["二氧化碳"], totalgas * 0.01f);
    }

    void AddGas(MatterGrid mg,MatterType mt,float volume)
    {
        float danqi = volume;
        Matter m = new Matter();
        m.Temperature = mg.Temperature;
        m.matterType = mt;
        m.currentMatterState = Matter.MatterState.Gas;
        m.Mass = danqi * GlobalConst.GetGasDensity(m.matterType.AtomicWeight, m.Temperature, GlobalConst.StandardPressure);
        mg.AddMatter(m);
    }

}
